﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.AudioVideoPlayback;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace XDMasterNetPlayer
{
    public partial class Master_Form : Form
    {
        public Master_Form()
        {
            InitializeComponent();
            SetFormFullScreen(true);

        }
        enum PlayerState
        {
            /// <summary>
            /// The stopped state of the player
            /// </summary>
            Stopped,

            /// <summary>
            /// The paused state of the player
            /// </summary>
            Paused,

            /// <summary>
            /// The playing state of the player
            /// </summary>
            Playing,

            /// <summary>
            /// The initial state of the player
            /// </summary>
            Initial
        }
        private readonly string filterText = "Video Files (*.avi;*.mp4 *.mov; *.mpg; *.mpeg; *.ts; *.wmv; *.vob; *.dat; *.rm; *.rmvb; *.flv)|*.avi;*.mp4; *.mov; *.mpg; *.mpeg; *.ts; *.wmv; *.vob; *.dat; *.rm; *.rmvb; *.flv";
        private Video ourVideo = null;
        private double duration;
        string fileName;
        ConfigInfo configDlg = null;
        XDUdpSocket udp;
        XDPlayerSocket playerSock;
        private PlayerState currentState = PlayerState.Initial;
        private void Form1_Load(object sender, EventArgs e)
        {
            configDlg = new ConfigInfo();
            configDlg.LoadData();
            udp = new XDUdpSocket(this);
            udp.strRemoteIP = configDlg.RemoteIP;
            udp.nRemotePort = configDlg.nRemotePort;
            udp.Create(configDlg.nLocalPort);
            timer_Connect.Start();
            playerSock = new XDPlayerSocket(this);
            playerSock.strSlaverIP = configDlg.SlaverIP;
            playerSock.nSlaverPort = configDlg.nSlaverPort;
            playerSock.Create(configDlg.nLocalPlayerPort);
            timer_Frame.Start();
        }
        //打开文件
        private void OpenFile()
        {
            try
            {
                CleanUp();
                if (File.Exists(fileName))
                {


                    ourVideo = new Video(fileName);
                    ourVideo.Ending += new EventHandler(ourVideo_Ending);
                    ourVideo.Owner = this.picPlayWindow;

                    // Start playing now:
                    ourVideo.Pause();
                    duration = ourVideo.Duration;//单位：秒
                    currentState = PlayerState.Paused;
                }
                else
                {
                    udp.Send("master file open fail");
                }
            }
            catch (System.Exception e)
            {
                MessageBox.Show("This file could not be opened, please make sure that you have installed the decoder!" + e.ToString(), "Error Information",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            this.Refresh();
        }
            
    
        private void btnOpen_Click(object sender, EventArgs e)
        {
             OpenFileDialog openFileDlg = new OpenFileDialog();

            openFileDlg.Filter = filterText;
            openFileDlg.Title = "Open video file";

            DialogResult dlgResult = openFileDlg.ShowDialog();
            if (dlgResult == DialogResult.OK)
            {
                fileName = openFileDlg.FileName;
                if (string.IsNullOrEmpty(fileName))
                {
                    MessageBox.Show("The file name must not be empty, please open again!", "Information",
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                    return;
                }
            }
            OpenFile();
            return;
        }
        //清理缓存
        private void CleanUp()
        {
            if (ourVideo != null)
            {
                ourVideo.Dispose();
                ourVideo = null;
            }
            currentState = PlayerState.Initial;
        }
        private void StopPlay()
        {
            if (ourVideo != null)
            {
                ourVideo.Stop();
                currentState = PlayerState.Stopped;
              
            }
        }

        void ourVideo_Ending(object sender, EventArgs e)
        {
            if (currentState == PlayerState.Initial&&ourVideo != null)
            {
                ourVideo.CurrentPosition = 0.0;
                XDPlayerData playerData; ;

                playerData.type = PlayerDataType.FRAME;
                playerData.data = 0.0;

                playerSock.Send(playerData);
            }
            else
            {
                StopPlay();
            }
            
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            StopPlay();
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            if (ourVideo != null)
            {

                ourVideo.Play();
                
                currentState = PlayerState.Playing;

            }
        }

        private void btnFullScreen_Click(object sender, EventArgs e)
        {
            if (ourVideo != null)
            {
                ourVideo.Fullscreen = true;
            }
            SetFormFullScreen(true);
            
        }

        private void btnOpenConfigFile_Click(object sender, EventArgs e)
        {

            configDlg.ShowDialog(this);
        }
        public void pauseString(object o, EventArgs e)
        {
            string command = udp.recvString;
            string[] s = command.Split(new char[] { '#' });
            string front = s[0];
            string back = s[1];
            back = back.Substring(0, back.Length - 2);
            if(front == "CONNECTED")
            {
                timer_Connect.Stop();
                PlayStartMovie();
            }
            if (front == "BOTH_PLAY_CONNECTED")
            {
                if (ourVideo != null)
                {
                    ourVideo.CurrentPosition = 0.0;
                }
            }
            if(front == "OPEN")
            {
                fileName = "Movies\\" + back + "_left" + configDlg.MovieExt;
                OpenFile();
                udp.Send("READY#00");
            }
            if (front == "PLAY")
            {
                if (ourVideo != null)
                {
                    ourVideo.Play();
                    ourVideo.Fullscreen = true;
                    currentState = PlayerState.Playing;
                }
            }
            if (front == "STOP")
            {
                StopPlaying();
            }
            if (front == "CLOSE")
            {
                timer_Connect.Start();
            }
            if (front == "SHUTDOWN_MACHINE")
            {
                Shutdown();
            }
        }
        private void StopPlaying()
        {
            if (ourVideo != null)
            {
                if(currentState != PlayerState.Initial)
                {
                    ourVideo.Stop();
                    currentState = PlayerState.Initial;
                    PlayStartMovie();
                }
                ourVideo.CurrentPosition = 0.0;
            }
            

        }
        public PictureBox getPictureBox()
        {
            return this.picPlayWindow;
        }
        private void timer_Connect_Tick(object sender, EventArgs e)
        {
            udp.Send("CONNECT#MPM");
        }
        private void PlayStartMovie()
        {
            string startMovie = System.IO.Directory.GetCurrentDirectory() + configDlg.LeftIdleMovie;
            fileName = startMovie;
            OpenFile();
            currentState = PlayerState.Initial;
            if (ourVideo != null)
            {
                ourVideo.Play();
                ourVideo.Fullscreen = true;
            }
        }
        /// <summary>  
        /// 设置全屏或这取消全屏  
        /// </summary>  
        /// <param name="fullscreen">true:全屏 false:恢复</param>  
        /// <param name="rectOld">设置的时候，此参数返回原始尺寸，恢复时用此参数设置恢复</param>  
        /// <returns>设置结果</returns>  
        public Boolean SetFormFullScreen(Boolean fullscreen)//, ref Rectangle rectOld
        {
            Rectangle rectOld = Rectangle.Empty;
            Int32 hwnd = 0;
            hwnd = FindWindow("Shell_TrayWnd", null);//获取任务栏的句柄

            if (hwnd == 0) return false;

            if (fullscreen)//全屏
            {
                ShowWindow(hwnd, SW_HIDE);//隐藏任务栏

                SystemParametersInfo(SPI_GETWORKAREA, 0, ref rectOld, SPIF_UPDATEINIFILE);//get  屏幕范围
                Rectangle rectFull = Screen.PrimaryScreen.Bounds;//全屏范围
                SystemParametersInfo(SPI_SETWORKAREA, 0, ref rectFull, SPIF_UPDATEINIFILE);//窗体全屏幕显示
                SetWindowLong(this.Handle, GWL_STYLE, (uint)(GetWindowLong(this.Handle, GWL_STYLE) & ~WS_CAPTION));
                ShowCursor(false);//隐藏鼠标
            }
            else//还原 
            {
                ShowWindow(hwnd, SW_SHOW);//显示任务栏
                SetWindowLong(this.Handle, GWL_STYLE, (uint)(GetWindowLong(this.Handle, GWL_STYLE) | WS_CAPTION));
                SystemParametersInfo(SPI_SETWORKAREA, 0, ref rectOld, SPIF_UPDATEINIFILE);//窗体还原
                ShowCursor(true);//还原鼠标
            }
            return true;
        }
        #region user32.dll
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "ShowCursor")]
        public extern static bool ShowCursor(bool bShow);
        [DllImport("user32.dll", EntryPoint = "ShowWindow")]
        public static extern Int32 ShowWindow(Int32 hwnd, Int32 nCmdShow);
        public const Int32 SW_SHOW = 5; public const Int32 SW_HIDE = 0;
        private const int GWL_STYLE = (-16);
        private const long WS_CAPTION = 0x00C00000L;
        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
        private static extern Int32 SystemParametersInfo(Int32 uAction, Int32 uParam, ref Rectangle lpvParam, Int32 fuWinIni);
        public const Int32 SPIF_UPDATEINIFILE = 0x1;
        public const Int32 SPI_SETWORKAREA = 47;
        public const Int32 SPI_GETWORKAREA = 48;

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        private static extern Int32 FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", SetLastError = true)]
        static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32.dll", SetLastError = true)]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, UInt32 dwNewLong);
        #endregion

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Escape)
            {
                if (ourVideo != null)
                {
                    ourVideo.Fullscreen = false;
                }
                SetFormFullScreen(false);

            }
        }

        private void Master_Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            SetFormFullScreen(false);
            udp.Send("CLOSE#00");
        }
        private void Shutdown()
        {
            Process pro = new Process();
            pro.StartInfo.FileName = "shutdown.exe";
            pro.StartInfo.Arguments = "-s -t 0";//延时时间为0（马上关机）
            pro.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动进程
            pro.StartInfo.CreateNoWindow = true;//不创建窗体
            pro.StartInfo.RedirectStandardOutput = true;
            pro.Start();
        }

        public void pausePlayerData(object o, EventArgs e)
        {

        }

        private void timer_Frame_Tick(object sender, EventArgs e)
        {
            if (ourVideo != null)
            {
                XDPlayerData playerData;;
                
                playerData.type = PlayerDataType.FRAME;
                playerData.data = ourVideo.CurrentPosition;

                playerSock.Send(playerData);
            }
            
        }

        private void openImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CleanUp();
            string imagePath = Directory.GetCurrentDirectory() + configDlg.LeftImage;
            if (File.Exists(imagePath))
            {
                picPlayWindow.Image = Image.FromFile(imagePath);
            }
        }

        private void openGradToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CleanUp();
            string imagePath = Directory.GetCurrentDirectory() + configDlg.GradImage;
             if (File.Exists(imagePath))
            {
                  picPlayWindow.Image = Image.FromFile(imagePath);
             }
        }
       
        
    }

}
